summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Lombardo <clombardo169@gmail.com>2023-03-11 06:34:09 +0100
committerbunnei <bunneidev@gmail.com>2023-06-03 09:05:39 +0200
commit42b3e72e9608584d873b78defc63bc61218efd5b (patch)
tree218d6115fc1e814676b5761520d75300cc290a3a
parentandroid: Convert MainActivity to Kotlin (diff)
downloadyuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.gz
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.bz2
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.lz
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.xz
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.tar.zst
yuzu-42b3e72e9608584d873b78defc63bc61218efd5b.zip
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java243
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt205
2 files changed, 205 insertions, 243 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java
deleted file mode 100644
index f7919e483..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * Copyright 2013 Dolphin Emulator Project
- * Licensed under GPLv2+
- * Refer to the license.txt file included.
- */
-
-package org.yuzu.yuzu_emu.overlay;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.view.MotionEvent;
-
-import org.yuzu.yuzu_emu.NativeLibrary;
-import org.yuzu.yuzu_emu.NativeLibrary.ButtonType;
-import org.yuzu.yuzu_emu.utils.EmulationMenuSettings;
-
-/**
- * Custom {@link BitmapDrawable} that is capable
- * of storing it's own ID.
- */
-public final class InputOverlayDrawableJoystick {
- // The ID value what type of joystick this Drawable represents.
- private int mJoystickId;
- // The ID value what type of button this Drawable represents.
- private int mButtonId;
- // The ID value what motion event is tracking
- private int mTrackId = -1;
- private float mXAxis;
- private float mYAxis;
- private int mControlPositionX, mControlPositionY;
- private int mWidth;
- private int mHeight;
- private Rect mVirtBounds;
- private Rect mOrigBounds;
- private BitmapDrawable mOuterBitmap;
- private BitmapDrawable mDefaultStateInnerBitmap;
- private BitmapDrawable mPressedStateInnerBitmap;
- private BitmapDrawable mBoundsBoxBitmap;
- private boolean mPressedState = false;
-
- /**
- * Constructor
- *
- * @param res {@link Resources} instance.
- * @param bitmapOuter {@link Bitmap} which represents the outer non-movable part of the joystick.
- * @param bitmapInnerDefault {@link Bitmap} which represents the default inner movable part of the joystick.
- * @param bitmapInnerPressed {@link Bitmap} which represents the pressed inner movable part of the joystick.
- * @param rectOuter {@link Rect} which represents the outer joystick bounds.
- * @param rectInner {@link Rect} which represents the inner joystick bounds.
- * @param joystick Identifier for which joystick this is.
- */
- public InputOverlayDrawableJoystick(Resources res, Bitmap bitmapOuter,
- Bitmap bitmapInnerDefault, Bitmap bitmapInnerPressed,
- Rect rectOuter, Rect rectInner, int joystick, int button) {
- mJoystickId = joystick;
- mButtonId = button;
-
- mOuterBitmap = new BitmapDrawable(res, bitmapOuter);
- mDefaultStateInnerBitmap = new BitmapDrawable(res, bitmapInnerDefault);
- mPressedStateInnerBitmap = new BitmapDrawable(res, bitmapInnerPressed);
- mBoundsBoxBitmap = new BitmapDrawable(res, bitmapOuter);
- mWidth = bitmapOuter.getWidth();
- mHeight = bitmapOuter.getHeight();
-
- setBounds(rectOuter);
- mDefaultStateInnerBitmap.setBounds(rectInner);
- mPressedStateInnerBitmap.setBounds(rectInner);
- mVirtBounds = getBounds();
- mOrigBounds = mOuterBitmap.copyBounds();
- mBoundsBoxBitmap.setAlpha(0);
- mBoundsBoxBitmap.setBounds(getVirtBounds());
- SetInnerBounds();
- }
-
- public void draw(Canvas canvas) {
- mOuterBitmap.draw(canvas);
- getCurrentStateBitmapDrawable().draw(canvas);
- mBoundsBoxBitmap.draw(canvas);
- }
-
- public boolean updateStatus(MotionEvent event) {
- int pointerIndex = event.getActionIndex();
- int xPosition = (int) event.getX(pointerIndex);
- int yPosition = (int) event.getY(pointerIndex);
- int pointerId = event.getPointerId(pointerIndex);
- int motion_event = event.getAction() & MotionEvent.ACTION_MASK;
- boolean isActionDown = motion_event == MotionEvent.ACTION_DOWN || motion_event == MotionEvent.ACTION_POINTER_DOWN;
- boolean isActionUp = motion_event == MotionEvent.ACTION_UP || motion_event == MotionEvent.ACTION_POINTER_UP;
-
- if (isActionDown) {
- if (!getBounds().contains(xPosition, yPosition)) {
- return false;
- }
- mPressedState = true;
- mOuterBitmap.setAlpha(0);
- mBoundsBoxBitmap.setAlpha(255);
- if (EmulationMenuSettings.getJoystickRelCenter()) {
- getVirtBounds().offset(xPosition - getVirtBounds().centerX(),
- yPosition - getVirtBounds().centerY());
- }
- mBoundsBoxBitmap.setBounds(getVirtBounds());
- mTrackId = pointerId;
- }
-
- if (isActionUp) {
- if (mTrackId != pointerId) {
- return false;
- }
- mPressedState = false;
- mXAxis = 0.0f;
- mYAxis = 0.0f;
- mOuterBitmap.setAlpha(255);
- mBoundsBoxBitmap.setAlpha(0);
- setVirtBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
- mOrigBounds.bottom));
- setBounds(new Rect(mOrigBounds.left, mOrigBounds.top, mOrigBounds.right,
- mOrigBounds.bottom));
- SetInnerBounds();
- mTrackId = -1;
- return true;
- }
-
- if (mTrackId == -1)
- return false;
-
- for (int i = 0; i < event.getPointerCount(); i++) {
- if (mTrackId != event.getPointerId(i)) {
- continue;
- }
- float touchX = event.getX(i);
- float touchY = event.getY(i);
- float maxY = getVirtBounds().bottom;
- float maxX = getVirtBounds().right;
- touchX -= getVirtBounds().centerX();
- maxX -= getVirtBounds().centerX();
- touchY -= getVirtBounds().centerY();
- maxY -= getVirtBounds().centerY();
- final float AxisX = touchX / maxX;
- final float AxisY = touchY / maxY;
- final float oldXAxis = mXAxis;
- final float oldYAxis = mYAxis;
-
- // Clamp the circle pad input to a circle
- final float angle = (float) Math.atan2(AxisY, AxisX);
- float radius = (float) Math.sqrt(AxisX * AxisX + AxisY * AxisY);
- if (radius > 1.0f) {
- radius = 1.0f;
- }
- mXAxis = ((float) Math.cos(angle) * radius);
- mYAxis = ((float) Math.sin(angle) * radius);
- SetInnerBounds();
- return oldXAxis != mXAxis && oldYAxis != mYAxis;
- }
-
- return false;
- }
-
- private void SetInnerBounds() {
- int X = getVirtBounds().centerX() + (int) ((mXAxis) * (getVirtBounds().width() / 2));
- int Y = getVirtBounds().centerY() + (int) ((mYAxis) * (getVirtBounds().height() / 2));
-
- if (X > getVirtBounds().centerX() + (getVirtBounds().width() / 2))
- X = getVirtBounds().centerX() + (getVirtBounds().width() / 2);
- if (X < getVirtBounds().centerX() - (getVirtBounds().width() / 2))
- X = getVirtBounds().centerX() - (getVirtBounds().width() / 2);
- if (Y > getVirtBounds().centerY() + (getVirtBounds().height() / 2))
- Y = getVirtBounds().centerY() + (getVirtBounds().height() / 2);
- if (Y < getVirtBounds().centerY() - (getVirtBounds().height() / 2))
- Y = getVirtBounds().centerY() - (getVirtBounds().height() / 2);
-
- int width = mPressedStateInnerBitmap.getBounds().width() / 2;
- int height = mPressedStateInnerBitmap.getBounds().height() / 2;
- mDefaultStateInnerBitmap.setBounds(X - width, Y - height, X + width, Y + height);
- mPressedStateInnerBitmap.setBounds(mDefaultStateInnerBitmap.getBounds());
- }
-
- public void setPosition(int x, int y) {
- mControlPositionX = x;
- mControlPositionY = y;
- }
-
- private BitmapDrawable getCurrentStateBitmapDrawable() {
- return mPressedState ? mPressedStateInnerBitmap : mDefaultStateInnerBitmap;
- }
-
- /**
- * Gets this InputOverlayDrawableJoystick's button ID.
- *
- * @return this InputOverlayDrawableJoystick's button ID.
- */
- public int getJoystickId() {
- return mJoystickId;
- }
-
- public float getXAxis() {
- return mXAxis;
- }
-
- public float getYAxis() {
- // Nintendo joysticks have y axis inverted
- return -mYAxis;
- }
-
- public int getButtonId() {
- return mButtonId;
- }
-
- public int getTrackId() {
- return mTrackId;
- }
-
- public int getButtonStatus() {
- // TODO: Add button support
- return NativeLibrary.ButtonState.RELEASED;
- }
-
- public Rect getBounds() {
- return mOuterBitmap.getBounds();
- }
-
- public void setBounds(Rect bounds) {
- mOuterBitmap.setBounds(bounds);
- }
-
- private Rect getVirtBounds() {
- return mVirtBounds;
- }
-
- private void setVirtBounds(Rect bounds) {
- mVirtBounds = bounds;
- }
-
- public int getWidth() {
- return mWidth;
- }
-
- public int getHeight() {
- return mHeight;
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt
new file mode 100644
index 000000000..84a3ea40b
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlayDrawableJoystick.kt
@@ -0,0 +1,205 @@
+package org.yuzu.yuzu_emu.overlay
+
+import android.content.res.Resources
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Rect
+import android.graphics.drawable.BitmapDrawable
+import android.view.MotionEvent
+import org.yuzu.yuzu_emu.NativeLibrary
+import org.yuzu.yuzu_emu.utils.EmulationMenuSettings
+import kotlin.math.atan2
+import kotlin.math.cos
+import kotlin.math.sin
+import kotlin.math.sqrt
+
+/**
+ * Custom [BitmapDrawable] that is capable
+ * of storing it's own ID.
+ *
+ * @param res [Resources] instance.
+ * @param bitmapOuter [Bitmap] which represents the outer non-movable part of the joystick.
+ * @param bitmapInnerDefault [Bitmap] which represents the default inner movable part of the joystick.
+ * @param bitmapInnerPressed [Bitmap] which represents the pressed inner movable part of the joystick.
+ * @param rectOuter [Rect] which represents the outer joystick bounds.
+ * @param rectInner [Rect] which represents the inner joystick bounds.
+ * @param joystickId The ID value what type of joystick this Drawable represents.
+ * @param buttonId The ID value what type of button this Drawable represents.
+ */
+class InputOverlayDrawableJoystick(
+ res: Resources,
+ bitmapOuter: Bitmap,
+ bitmapInnerDefault: Bitmap,
+ bitmapInnerPressed: Bitmap,
+ rectOuter: Rect,
+ rectInner: Rect,
+ val joystickId: Int,
+ val buttonId: Int
+) {
+
+ // The ID value what motion event is tracking
+ var trackId = -1
+ var xAxis = 0f
+ private var yAxis = 0f
+ private var controlPositionX = 0
+ private var controlPositionY = 0
+ val width: Int
+ val height: Int
+ private var virtBounds: Rect
+ private val origBounds: Rect
+ private val outerBitmap: BitmapDrawable
+ private val defaultStateInnerBitmap: BitmapDrawable
+ private val pressedStateInnerBitmap: BitmapDrawable
+ private val boundsBoxBitmap: BitmapDrawable
+ private var pressedState = false
+
+ // TODO: Add button support
+ val buttonStatus: Int
+ get() =
+ NativeLibrary.ButtonState.RELEASED
+ var bounds: Rect?
+ get() = outerBitmap.bounds
+ set(bounds) {
+ outerBitmap.bounds = bounds!!
+ }
+
+ // Nintendo joysticks have y axis inverted
+ val realYAxis: Float
+ get() = -yAxis
+
+ private val currentStateBitmapDrawable: BitmapDrawable
+ get() = if (pressedState) pressedStateInnerBitmap else defaultStateInnerBitmap
+
+ init {
+ outerBitmap = BitmapDrawable(res, bitmapOuter)
+ defaultStateInnerBitmap = BitmapDrawable(res, bitmapInnerDefault)
+ pressedStateInnerBitmap = BitmapDrawable(res, bitmapInnerPressed)
+ boundsBoxBitmap = BitmapDrawable(res, bitmapOuter)
+ width = bitmapOuter.width
+ height = bitmapOuter.height
+ bounds = rectOuter
+ defaultStateInnerBitmap.bounds = rectInner
+ pressedStateInnerBitmap.bounds = rectInner
+ virtBounds = bounds!!
+ origBounds = outerBitmap.copyBounds()
+ boundsBoxBitmap.alpha = 0
+ boundsBoxBitmap.bounds = virtBounds
+ setInnerBounds()
+ }
+
+ fun draw(canvas: Canvas?) {
+ outerBitmap.draw(canvas!!)
+ currentStateBitmapDrawable.draw(canvas)
+ boundsBoxBitmap.draw(canvas)
+ }
+
+ fun updateStatus(event: MotionEvent): Boolean {
+ val pointerIndex = event.actionIndex
+ val xPosition = event.getX(pointerIndex).toInt()
+ val yPosition = event.getY(pointerIndex).toInt()
+ val pointerId = event.getPointerId(pointerIndex)
+ val motionEvent = event.action and MotionEvent.ACTION_MASK
+ val isActionDown =
+ motionEvent == MotionEvent.ACTION_DOWN || motionEvent == MotionEvent.ACTION_POINTER_DOWN
+ val isActionUp =
+ motionEvent == MotionEvent.ACTION_UP || motionEvent == MotionEvent.ACTION_POINTER_UP
+ if (isActionDown) {
+ if (!bounds!!.contains(xPosition, yPosition)) {
+ return false
+ }
+ pressedState = true
+ outerBitmap.alpha = 0
+ boundsBoxBitmap.alpha = 255
+ if (EmulationMenuSettings.joystickRelCenter) {
+ virtBounds.offset(
+ xPosition - virtBounds.centerX(),
+ yPosition - virtBounds.centerY()
+ )
+ }
+ boundsBoxBitmap.bounds = virtBounds
+ trackId = pointerId
+ }
+ if (isActionUp) {
+ if (trackId != pointerId) {
+ return false
+ }
+ pressedState = false
+ xAxis = 0.0f
+ yAxis = 0.0f
+ outerBitmap.alpha = 255
+ boundsBoxBitmap.alpha = 0
+ virtBounds = Rect(
+ origBounds.left,
+ origBounds.top,
+ origBounds.right,
+ origBounds.bottom
+ )
+ bounds = Rect(
+ origBounds.left,
+ origBounds.top,
+ origBounds.right,
+ origBounds.bottom
+ )
+ setInnerBounds()
+ trackId = -1
+ return true
+ }
+ if (trackId == -1) return false
+ for (i in 0 until event.pointerCount) {
+ if (trackId != event.getPointerId(i)) {
+ continue
+ }
+ var touchX = event.getX(i)
+ var touchY = event.getY(i)
+ var maxY = virtBounds.bottom.toFloat()
+ var maxX = virtBounds.right.toFloat()
+ touchX -= virtBounds.centerX().toFloat()
+ maxX -= virtBounds.centerX().toFloat()
+ touchY -= virtBounds.centerY().toFloat()
+ maxY -= virtBounds.centerY().toFloat()
+ val axisX = touchX / maxX
+ val axisY = touchY / maxY
+ val oldXAxis = xAxis
+ val oldYAxis = yAxis
+
+ // Clamp the circle pad input to a circle
+ val angle = atan2(axisY.toDouble(), axisX.toDouble()).toFloat()
+ var radius = sqrt((axisX * axisX + axisY * axisY).toDouble()).toFloat()
+ if (radius > 1.0f) {
+ radius = 1.0f
+ }
+ xAxis = cos(angle.toDouble()).toFloat() * radius
+ yAxis = sin(angle.toDouble()).toFloat() * radius
+ setInnerBounds()
+ return oldXAxis != xAxis && oldYAxis != yAxis
+ }
+ return false
+ }
+
+ private fun setInnerBounds() {
+ var x = virtBounds.centerX() + (xAxis * (virtBounds.width() / 2)).toInt()
+ var y = virtBounds.centerY() + (yAxis * (virtBounds.height() / 2)).toInt()
+ if (x > virtBounds.centerX() + virtBounds.width() / 2) x =
+ virtBounds.centerX() + virtBounds.width() / 2
+ if (x < virtBounds.centerX() - virtBounds.width() / 2) x =
+ virtBounds.centerX() - virtBounds.width() / 2
+ if (y > virtBounds.centerY() + virtBounds.height() / 2) y =
+ virtBounds.centerY() + virtBounds.height() / 2
+ if (y < virtBounds.centerY() - virtBounds.height() / 2) y =
+ virtBounds.centerY() - virtBounds.height() / 2
+ val width = pressedStateInnerBitmap.bounds.width() / 2
+ val height = pressedStateInnerBitmap.bounds.height() / 2
+ defaultStateInnerBitmap.setBounds(
+ x - width,
+ y - height,
+ x + width,
+ y + height
+ )
+ pressedStateInnerBitmap.bounds = defaultStateInnerBitmap.bounds
+ }
+
+ fun setPosition(x: Int, y: Int) {
+ controlPositionX = x
+ controlPositionY = y
+ }
+}